package edu.xust.utils;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.util.*;

/**
 * @author:LG
 * @date:Created at 2018/11/02
 */
public class UploadUtil {

    /**
     * 上传的路径
     */
    public static String uploadPath = "";

    /**
     * 备份的路径
     */
    public static String backupPath = "";

    /**
     * 单个文件上传大小(字节)
     */
    private static Long fileMaxSize = 1024*1024*2L;

    /**
     * 总的文件上传大小
     */
    private static Long fileAllMaxSize = 1024*1024*5L;

    /**
     * 允许上传的后缀
     */
    private static String allowExts = ".jpg|.png|.gif|.xls";

    // 加载配置文件
    static {
        try {
            // 获取配置文件数据
            InputStream inputStream = UploadUtil.class.getClassLoader().getResourceAsStream("upload.properties");
            Properties properties = new Properties();
            properties.load(inputStream);
            // 给属性赋值
            uploadPath = properties.getProperty("uploadPath");
            backupPath = properties.getProperty("backupPath");
            System.out.println(backupPath +"............................back");
            fileMaxSize = Long.valueOf(properties.getProperty("fileMaxSize"));
            fileAllMaxSize = Long.valueOf(properties.getProperty("fileAllMaxSize"));
            allowExts = properties.getProperty("allowExts");
        } catch (IOException e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 结果Map
     */
    private Map<String,Object> resultMap = new HashMap<>(16);


    /**
     * 表单数据
     */
    private Map<String,String> formData = new HashMap<>();

    /*文件名集合*/
    private List<String> fileNames = new ArrayList<String>();
    //上传文件的模块名
    private String modelName;

    public Map<String, String> getFormData() {
        return formData;
    }

    public void setFormData(Map<String, String> formData) {
        this.formData = formData;
    }

    /**
     * 文件上传的方法
     * @param request
     */
    public Map<String,Map<String,Object>> upload(HttpServletRequest request){

        // 1.创建临时工厂
        DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();

        // 2. 实例化核心上传类
        ServletFileUpload servletFileUpload = new ServletFileUpload(diskFileItemFactory);

        // 3. 设置初始化参数
        // 设置单个文件的大小
        servletFileUpload.setFileSizeMax(fileMaxSize);
        // 设置总的文件大小
        servletFileUpload.setSizeMax(fileAllMaxSize);
        HashMap<String, Map<String, Object>> returnMap = new HashMap<>();

        try {
            // 4. 解析请求
            List<FileItem> fileItems = servletFileUpload.parseRequest(request);
            if (fileItems == null || fileItems.size() == 0) {
                returnMap.put("error", null);//如果没有文件 结果为出错
            } else {
                // 遍历
                for (FileItem item : fileItems) {
                    // 区分普通表单项和文件项
                    if (item.isFormField()) {
                        // 是表单项
                        // 表单的name属性值
                        String name = item.getFieldName();
                        // 获取对应的值
                        modelName = item.getString("utf-8");

                        formData.put(name, modelName);
                    } else {
                        // 文件项

                        // 获取文件名
                        String name = item.getName();
                        // 组装一个新的名字
                        String uid = UUIDUtil.getUid();
                        // 获取后缀
                        String ext = name.substring(name.lastIndexOf("."), name.length());
                        // 限制后缀
                        if (allowExts.indexOf(ext) == -1) {
                            throw new FileUploadException("后缀不允许!");
                        }
                        // 组装一个日期路径
                        String datePath = getPath(uploadPath+"/"+modelName);
                        // 组装一个日期路径
                        String backupDatePath = getPath(backupPath+"/"+modelName);
                        // 存到数据库的路径
                        String dbPath = datePath + "/" + uid + ext;
                        String backupdbPath = backupDatePath + "/" + uid + ext;
                        System.out.println("dbPath");
                        System.out.println(dbPath);

                        // 抽象一个文件对象
                        File file = new File(uploadPath + "/"+modelName +"/"+ dbPath);
                        File backFile = new File(backupPath + "/"+modelName +"/" + backupdbPath);


                        // 上传
                        item.write(file);
//                        item.write(backFile);

                        BufferedInputStream inputStream = new
                                BufferedInputStream(new FileInputStream(file));
                        BufferedOutputStream outputStream = new
                                BufferedOutputStream(new FileOutputStream(backFile),900);

                        byte[] bytes = new byte[2048];
                        int len = 0;
                        while ((len = inputStream.read(bytes)) != -1){
                            outputStream.write(bytes,0,len);
                        }

                        outputStream.flush();//将当前输出流还在缓存中的数据写出 保证不丢失数据
                        outputStream.close();


                        // 将临时文件删除
                        item.delete();

                        // 保存上传的文件名
                        formData.put(item.getFieldName(), dbPath);
                        fileNames.add(dbPath);
                        resultMap.put("fileNameList",fileNames);
                    }
                }

                resultMap.put("code", 200);
                resultMap.put("msg", "上传成功!");


            returnMap.put("success",resultMap);
        }
        } catch(Exception e){
            resultMap.put("code", 400);
            resultMap.put("msg", e.getMessage());//普通错误提示给普通用户看
            resultMap.put("exception",e);//异常代码给运维看
            e.printStackTrace();
        }
        return returnMap;
    }


    /**
     * 文件上传内部的路径
     * @param uploadPath : 上传的根路径
     * @return
     */
    private static String getPath(String uploadPath){

        Calendar calendar = Calendar.getInstance();
        // 获取年
        int year = calendar.get(Calendar.YEAR);
        // 获取月
        int month = calendar.get(Calendar.MONTH)+1;
        // 获取日
        int day = calendar.get(Calendar.DAY_OF_MONTH);

        String datePath = year+"/"+month+"/"+day;

        String path = uploadPath+"/"+datePath;

        File file = new File(path);
        if (!file.exists()) {
            file.mkdirs();
        }
        return datePath;
    }


    @Override
    public String toString() {
        return "UploadUtil{" +
                "resultMap=" + resultMap +
                ", formData=" + formData +
                '}';
    }
}
